package dnl.toolbox.xml;

import java.io.File;
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.lang.reflect.Constructor;

import dnl.toolbox.io.FileSystemResource;
import dnl.toolbox.io.Resource;

/**
 * A utility class for IO related issues of XML resources.
 * 
 * @author Daniel Orr
 * 
 */
public class XmlUtils {

	/**
	 * 
	 * @param resource
	 * @return
	 * @throws IOException
	 */
	public static Reader getReaderForXmlResource(Resource resource) throws IOException {
		return getReaderForXmlResource(resource, null);
	}

	/**
	 * 
	 * @param file
	 * @return
	 * @throws IOException
	 */
	public static Reader getReaderForXmlFile(File file) throws IOException {
		return getReaderForXmlFile(file, null);
	}

	/**
	 * Gets a <code>Reader</code> for the given resource after attempting to
	 * resolve the corresponding encoding.
	 * 
	 * @param resource
	 *            a resource
	 * @param filterClass
	 *            any decoration on the stream created to get the given resource
	 *            can be given by this filter.
	 * @return a <code>Reader</code> ready for reading the given resource.
	 * @throws IOException
	 */
	public static Reader getReaderForXmlResource(Resource resource,
			Class<? extends FilterInputStream> filterClass) throws IOException {
		InputStream is;
		if (filterClass == null) {
			is = resource.getInputStream();
		} else {
			Constructor<? extends FilterInputStream> constructor;
			try {
				constructor = filterClass
						.getConstructor(InputStream.class);
				is = constructor.newInstance(resource.getInputStream());
			} catch (Exception e) {
				e.printStackTrace();
				throw new IllegalArgumentException(e);
			}
		}
		String encoding = XmlEncodingDetector.detectEncoding(resource, true);
		InputStreamReader reader = new InputStreamReader(is, encoding);
		return reader;
	}

	public static Reader getReaderForXmlFile(File f,
			Class<? extends FilterInputStream> filterClass) throws IOException {
		return getReaderForXmlResource(new FileSystemResource(f), filterClass);
	}
	
}
